package com.njlime.core.web.validation.annotation.support;

import com.njlime.core.web.validation.RegexType;
import com.njlime.core.web.validation.annotation.Validate;
import com.njlime.core.web.validation.utils.RegexUtils;
import com.njlime.core.web.validation.utils.StringUtils;

import java.lang.reflect.Field;

/**
 * 注解解析
 *
 * @author Goofy
 */
public class ValidateService {

    private static Validate validate;

    public ValidateService() {
        super();
    }

    //解析的入口
    public static void valid(Object object) throws Exception {
        //获取object的类型
        Class<? extends Object> clazz = object.getClass();
        //获取该类型声明的成员
        Field[] fields = clazz.getDeclaredFields();
        //遍历属性
        for (Field field : fields) {
            //对于private私有化的成员变量，通过setAccessible来修改器访问权限
            field.setAccessible(true);
            validate(field, object);
            //重新设置会私有权限
            field.setAccessible(false);
        }
    }


    public static void validate(Field field, Object object) throws Exception {

        String description;
        Object value;

        //获取对象的成员的注解信息
        validate = field.getAnnotation(Validate.class);
        value = field.get(object);

        if (validate == null) return;

        description = validate.description().equals("") ? field.getName() : validate.description();

        /*************注解解析工作开始******************/
        if (!validate.nullable()) {
            if (value == null || StringUtils.isBlank(value.toString())) {
                throw new Exception(description + "不能为空");
            }
        }

        if (value != null && value.toString().length() > validate.maxLength() && validate.maxLength() != 0) {
            throw new Exception(description + "长度不能超过" + validate.maxLength());
        }

        if (value != null && value.toString().length() < validate.minLength() && validate.minLength() != 0) {
            throw new Exception(description + "长度不能小于" + validate.minLength());
        }

        if (validate.regexType() != RegexType.NONE) {
            switch (validate.regexType()) {
                case NONE:
                    break;
                case SPECIALCHAR:
                    if (value != null && RegexUtils.hasSpecialChar(value.toString())) {
                        throw new Exception(description + "不能含有特殊字符");
                    }
                    break;
                case CHINESE:
                    if (value != null && RegexUtils.isChinese2(value.toString())) {
                        throw new Exception(description + "不能含有中文字符");
                    }
                    break;
                case EMAIL:
                    if (value != null && !RegexUtils.isEmail(value.toString())) {
                        throw new Exception(description + "地址格式不正确");
                    }
                    break;
                case IP:
                    if (value != null && !RegexUtils.isIp(value.toString())) {
                        throw new Exception(description + "地址格式不正确");
                    }
                    break;
                case NUMBER:
                    if (value != null && !RegexUtils.isNumber(value.toString())) {
                        throw new Exception(description + "不是数字");
                    }
                    break;
                case AMOUNT:
                    if (value != null && !RegexUtils.isDecimal(value.toString(),2)) {
                        throw new Exception(description + "不是金额格式");
                    }
                    break;
                case PHONENUMBER:
                    if (value != null && !RegexUtils.isPhoneNumber(value.toString())) {
                        throw new Exception(description + "格式不正确");
                    }
                    break;
                default:
                    break;
            }
        }

        if (!validate.regexExpression().equals("")) {
            if (value.toString().matches(validate.regexExpression())) {
                throw new Exception(description + "格式不正确");
            }
        }
        /*************注解解析工作结束******************/
    }
}
